package com.duguo.dynamicmvc.factory.processor.controller;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javassist.CtClass;
import javassist.CtMethod;

import com.duguo.dynamicmvc.factory.ControllerBuilder;
import com.duguo.dynamicmvc.factory.ControllerFactory;
import com.duguo.dynamicmvc.factory.WorkingModel;

public class ControllerProcessorImpl implements ControllerProcessor{

	ControllerClassCreator _controllerClassCreator;
	ControllerMultiActionCreator _controllerMultiActionCreator;
	ControllerMethodCreator _controllerMethodCreator;
	ControllerNameBuilder _controllerNameBuilder;
	ControllerInjectionCreator _controllerInjectionCreator;
	
	public void setupInjectionFeilds(CtClass controllerCtClass) throws Exception{
		_controllerInjectionCreator.setupInjectionFeilds(controllerCtClass);
	}

	public void injectionFeilds(Object controllerInstance) throws Exception{
		_controllerInjectionCreator.injectionFeilds(controllerInstance);
	}
	
	public void createInternalMethodControllerHandlerMethod(WorkingModel workingModel, CtClass internalControllerClass, CtMethod controllerMethodCtMethod, ControllerBuilder controllerBuilder) throws Exception{
		_controllerMethodCreator.createInternalMethodControllerHandlerMethod(workingModel, internalControllerClass, controllerMethodCtMethod, controllerBuilder);
	}

	public ControllerFactory getParentControllerFactory(WorkingModel workingModel){
		return _controllerClassCreator.getParentControllerFactory(workingModel);
	}

	public void setupControllerClass(WorkingModel workingModel) throws Exception{
		_controllerClassCreator.setupControllerClass(workingModel);
	}
	
	public void setupMultiActionControllerCtClass(CtClass controllerCtClass, CtMethod controllerHandlerCtMethod, boolean hasDynamicController, Map<String,Object> viewMappings, CtClass controllerInternalInterface, boolean isSingleAction, ControllerBuilder controllerBuilder) throws Exception{
		_controllerMultiActionCreator.setupMultiActionControllerCtClass(controllerCtClass, controllerHandlerCtMethod, hasDynamicController, viewMappings, controllerInternalInterface, isSingleAction, controllerBuilder);
	}

	public void setupDynamicControllerParentHandler(CtClass controllerCtClass, CtClass parentInternalInterfaceCtClass, CtMethod parentHandlerCtMethod) throws Exception{
		_controllerMultiActionCreator.setupDynamicControllerParentHandler(controllerCtClass, parentInternalInterfaceCtClass, parentHandlerCtMethod,this);
	}


	
    public CtClass getViewCtClass()  throws Exception {
        return _controllerClassCreator.getViewCtClass();
    }
    

    public void setupDynamicControllerName(WorkingModel workingModel) throws Exception{
    	_controllerClassCreator.setupDynamicControllerName(workingModel);
    }
	
    public List<CtMethod> getControllerMethods(CtClass controllerCtClass) throws Exception {
    	List<CtMethod> allMethods=new ArrayList<CtMethod>();
    	for (CtMethod controllerMethodCtMethod : controllerCtClass.getMethods()) {
            if (_controllerClassCreator.isControllerMethod(controllerMethodCtMethod)) {
            	allMethods.add(controllerMethodCtMethod);
            }
        }
        return allMethods;
    }

    public CtMethod findDynamicMethod(CtClass controllerCtClass) throws Exception {
        for (CtMethod ctMethod : controllerCtClass.getMethods()) {
            if (ctMethod.getName().equals("resolve") &&
                    !Modifier.isAbstract(ctMethod.getModifiers()) &&
                    Modifier.isPublic(ctMethod.getModifiers()) &&
                    ctMethod.getParameterTypes().length >= 1 &&
                    ctMethod.getReturnType() != CtClass.voidType)
                return ctMethod;
        }
        if (controllerCtClass.getSuperclass() != null) {
            return findDynamicMethod(controllerCtClass.getSuperclass());
        }
        return null;
    }

	public ControllerClassCreator getControllerClassCreator() {
		return _controllerClassCreator;
	}

	public void setControllerClassCreator(
			ControllerClassCreator controllerClassCreator) {
		_controllerClassCreator = controllerClassCreator;
	}

	public ControllerMultiActionCreator getControllerMultiActionCreator() {
		return _controllerMultiActionCreator;
	}

	public void setControllerMultiActionCreator(
			ControllerMultiActionCreator controllerMultiActionCreator) {
		_controllerMultiActionCreator = controllerMultiActionCreator;
	}

	public ControllerMethodCreator getControllerMethodCreator() {
		return _controllerMethodCreator;
	}

	public void setControllerMethodCreator(
			ControllerMethodCreator controllerMethodCreator) {
		_controllerMethodCreator = controllerMethodCreator;
	}

	public ControllerNameBuilder getControllerNameBuilder() {
		return _controllerNameBuilder;
	}

	public void setControllerNameBuilder(ControllerNameBuilder controllerNameBuilder) {
		_controllerNameBuilder = controllerNameBuilder;
	}

	public ControllerInjectionCreator getControllerInjectionCreator() {
		return _controllerInjectionCreator;
	}

	public void setControllerInjectionCreator(
			ControllerInjectionCreator controllerInjectionCreator) {
		_controllerInjectionCreator = controllerInjectionCreator;
	}
    
}
